import { useState, useRef, useEffect } from "react"

const UseRefDemo = () => {
  // 1. 基本用法 - 引用DOM元素
  const inputRef = useRef<HTMLInputElement>(null)

  // 2. 存储不触发渲染的值
  const renderCountRef = useRef(0)
  const [count, setCount] = useState(0)
  const prevCountRef = useRef(count)

  // 3. 定时器示例
  const [timer, setTimer] = useState(0)
  const intervalRef = useRef<number | null>(null)

  // 跟踪渲染次数
  useEffect(() => {
    renderCountRef.current += 1
  })

  // 记录前一个值
  useEffect(() => {
    prevCountRef.current = count
  }, [count])

  // 聚焦输入框
  const handleFocus = () => {
    if (inputRef.current) {
      inputRef.current.focus()
    }
  }

  // 定时器操作
  const startTimer = () => {
    if (intervalRef.current !== null) return
    intervalRef.current = window.setInterval(() => {
      setTimer((t) => t + 1)
    }, 1000)
  }

  const stopTimer = () => {
    if (intervalRef.current === null) return
    clearInterval(intervalRef.current)
    intervalRef.current = null
  }

  const resetTimer = () => {
    stopTimer()
    setTimer(0)
  }

  // 清理定时器
  useEffect(() => {
    return () => {
      if (intervalRef.current !== null) {
        clearInterval(intervalRef.current)
      }
    }
  }, [])

  return (
    <div className="demo-section">
      <h2>useRef Hook 面试题讲解</h2>

      <div className="card">
        <h3>1. 什么是 useRef?</h3>
        <p>
          useRef 是一个 React Hook，它返回一个可变的 ref 对象，其 .current
          属性被初始化为传入的参数。 返回的对象在组件的整个生命周期内保持不变。
        </p>

        <div className="code-example">
          <code>const refContainer = useRef(initialValue)</code>
        </div>
      </div>

      <div className="card">
        <h3>2. 常见面试问题: useRef 的主要用途是什么?</h3>

        <p>useRef 有两个主要用途:</p>
        <ol>
          <li>访问 DOM 元素</li>
          <li>保存不会触发重新渲染的可变值</li>
        </ol>
      </div>

      <div className="card">
        <h3>3. 使用 useRef 访问 DOM 元素</h3>

        <div className="example-output">
          <input
            ref={inputRef}
            type="text"
            placeholder="点击按钮聚焦这个输入框"
          />
          <button onClick={handleFocus}>聚焦输入框</button>
        </div>

        <div className="code-example">
          <code>
            const inputRef = useRef(null);
            {"<input ref={inputRef} />"}
            // 访问DOM元素 inputRef.current.focus();
          </code>
        </div>
      </div>

      <div className="card">
        <h3>4. 常见面试问题: useRef vs useState 的区别?</h3>

        <p>
          <strong>useRef:</strong>
          <ul>
            <li>修改 .current 不会触发组件重新渲染</li>
            <li>在组件的整个生命周期内保持不变</li>
            <li>变更是同步的</li>
          </ul>

          <strong>useState:</strong>
          <ul>
            <li>修改状态会触发组件重新渲染</li>
            <li>每次重新渲染时都会返回最新状态值</li>
            <li>状态更新是异步的</li>
          </ul>
        </p>
      </div>

      <div className="card">
        <h3>5. 使用场景: 存储不触发重新渲染的值</h3>

        <div className="example-output">
          <p>
            当前计数: <strong>{count}</strong>
          </p>
          <p>
            前一个计数: <strong>{prevCountRef.current}</strong>
          </p>
          <p>
            此组件已渲染 <strong>{renderCountRef.current}</strong> 次
          </p>
          <button onClick={() => setCount(count + 1)}>增加计数</button>
        </div>

        <div className="code-example">
          <code>
            // 跟踪渲染次数 const renderCountRef = useRef(0); useEffect((){" "}
            {/* jsx-to-string */ "=>"} {"{"}
            renderCountRef.current += 1;
            {"}"}); // 记录前一个值 const prevCountRef = useRef(count);
            useEffect(() {/* jsx-to-string */ "=>"} {"{"}
            prevCountRef.current = count;
            {"}"}, [count]);
          </code>
        </div>
      </div>

      <div className="card">
        <h3>6. 使用场景: 保存定时器 ID</h3>

        <div className="example-output">
          <p>
            定时器计时: <strong>{timer}</strong> 秒
          </p>
          <button onClick={startTimer} disabled={intervalRef.current !== null}>
            开始
          </button>
          <button onClick={stopTimer} disabled={intervalRef.current === null}>
            暂停
          </button>
          <button onClick={resetTimer}>重置</button>
        </div>

        <div className="code-example">
          <code>
            const intervalRef = useRef(null); const startTimer = (){" "}
            {/* jsx-to-string */ "=>"} {"{"}
            intervalRef.current = setInterval(() {/* jsx-to-string */ "=>"}{" "}
            {"{"}
            // 某些操作
            {"}"}, 1000);
            {"}"}; const stopTimer = () {/* jsx-to-string */ "=>"} {"{"}
            clearInterval(intervalRef.current); intervalRef.current = null;
            {"}"};
          </code>
        </div>
      </div>

      <div className="card">
        <h3>7. 常见面试问题: useRef 与 createRef 的区别?</h3>

        <p>
          <strong>useRef</strong>{" "}
          在组件的整个生命周期内保持不变，每次渲染返回同一个 ref 对象。
        </p>
        <p>
          <strong>createRef</strong> 每次渲染都会创建一个新的 ref
          对象，因此在函数组件中不适合使用。
        </p>
      </div>

      <div className="card">
        <h3>8. useRef 面试核心要点</h3>
        <ul>
          <li>useRef 返回的对象在组件的整个生命周期内保持不变</li>
          <li>修改 .current 属性不会触发组件重新渲染</li>
          <li>
            useRef 可以用来访问 DOM 元素、存储前一个状态值、保存定时器 ID 等
          </li>
          <li>useRef 是解决闭包陈旧值问题的方案之一</li>
          <li>与 forwardRef 结合可以将 ref 转发给子组件</li>
          <li>useRef 不仅限于 DOM 引用，可以引用任何可变值</li>
        </ul>
      </div>
    </div>
  )
}

export default UseRefDemo
